package com.itlong.cloud.commons.chinapay.service.impl;

import chinapay.Base64;
import chinapay.PrivateKey;
import chinapay.SecureLink;
import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.PO.AmountChangeInfoPO;
import com.itlong.cloud.POJO.PO.OperateTransferPropertyPO;
import com.itlong.cloud.POJO.VO.operate.ChinaPayWithdrawVO;
import com.itlong.cloud.POJO.VO.operate.OperateTransferAccountVO;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.operate.dao.IOperateBalanceAccountDao;
import com.itlong.cloud.operate.dao.IOperateWithdrawDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.random.LogicIdUtil;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import com.itlong.cloud.POJO.DTO.operate.ChinaPayTransactionBeanDTO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.commons.chinapay.dao.IChinaPayTransferAccountDao;
import com.itlong.cloud.commons.chinapay.service.IChinaPayTransferAccountService;
import com.itlong.cloud.utils.random.RandomUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <desc>
 * 银联转账-服务接口实现类.
 * </desc>
 *
 * @createDate 2018/9/1
 */
@Service
@RefreshScope
public class ChinaPayTransferAccountServiceImpl implements IChinaPayTransferAccountService{
    private static final Logger LOG = LoggerFactory.getLogger(ChinaPayTransferAccountServiceImpl.class);

    @Value("${"+ PlatformConstants.CHINAPAY_PAY_URL +"}")
    private String CHINAPAY_PAY_URL;

    @Value("${"+ PlatformConstants.MERKEY_PATH +"}")
    private String MERKEY_PATH;

    @Value("${"+ PlatformConstants.PUBKEY_PATH +"}")
    private String PUBKEY_PATH;

    @Value("${"+ PlatformConstants.MERID +"}")
    private String MERID;

    @Value("${"+ PlatformConstants.VERSION +"}")
    private String VERSION;

    @Value("${"+ PlatformConstants.SIGN_FLAG +"}")
    private String SIGN_FLAG;

    @Value("${"+ PlatformConstants.BALANCE_QUERY +"}")
    private String BALANCE_QUERY;

    @Value("${"+ PlatformConstants.QUERY_ORDER +"}")
    private String QUERY_ORDER;

    @Autowired
    IChinaPayTransferAccountDao iChinaPayTransferAccountDao;

    @Autowired
    IChinaPayTransferAccountService iChinaPayTransferAccountService;

    @Autowired
    IOperateBalanceAccountDao iOperateBalanceAccountDao;

    @Autowired
    IOperateWithdrawDao iOperateWithdrawDao;

    @Autowired
    private MessageSender messageSender;

    ExecutorService cachedThreadPool;

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");

    @PostConstruct
    public void init(){
        cachedThreadPool = Executors.newFixedThreadPool(1);
    }

    /**
     * <desc>
     *      根据提现记录ID向物业公司转账
     * <desc/>
     *
     * @param cashIds 提现记录ID,逗号分隔
     * @return
     * @author Juguang.S
     * @createDate 2018-09-01
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void transferAccount(String cashIds,String myUserName) throws Exception {
        //由于银联终止合作，暂时审批通过后支付状态改为已提现成功 为逻辑提现
        String[] cashIdArr = cashIds.split(",");
        for(String cashId : cashIdArr) {
            //根据提现ID查询提现金额、手续费和所转账的银行卡等信息
            OperateTransferAccountVO accountVO = iChinaPayTransferAccountDao.getBankCardInfoByCashId(cashId);
            //获取银联的手续费
            String fee = iChinaPayTransferAccountDao.getChinaPayHandFee();
            if(StringUtils.isEmpty(fee)){
                fee = "2";
            }
            if(accountVO!=null) {
                String projectId = accountVO.getProjectId();
                String total = accountVO.getAmount().subtract(accountVO.getHandlingFee()).toString();
                String merSeqId = LogicIdUtil.bussinessId().substring(0, 16);
                OperateTransferPropertyPO transferPropertyPO = new OperateTransferPropertyPO(accountVO.getCashId());
                transferPropertyPO.setTradeStatus(ChinaPayTradeStatusEnum.TRADE_SUCCESS.getType());
                transferPropertyPO.setTradeTime(new Date());
                transferPropertyPO.setSerualNumber(merSeqId);
                //保存资金变动明细 银联转账备付金变化明细
                //AmountChangeInfoPO changeInfoPO = new AmountChangeInfoPO(LogicIdUtil.bussinessId(), new BigDecimal(total), merSeqId, "", "");
                //changeInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
                //changeInfoPO.setCreateTime(new Date());
                //String accountBalance = this.getAccountBalance();
                //changeInfoPO.setTradeBeforeAmount(BigDecimal.valueOf(Double.valueOf(accountBalance) / 100).add(new BigDecimal(total)).add(new BigDecimal(fee)));
                //changeInfoPO.setTradeAfterAmount(BigDecimal.valueOf(Double.valueOf(accountBalance) / 100));
                //changeInfoPO.setThirdPartyPayment(2);
                //changeInfoPO.setTradeType(TradeTypeEnum.CHINA_PAY_FEE.getType());
                //changeInfoPO.setHandlingFee(new BigDecimal(fee));
                //iOperateBalanceAccountDao.save(SqlUtil.durableData(changeInfoPO, PlatformConstants.TABLE_SAVE));

                AmountChangeInfoPO InfoPO = new AmountChangeInfoPO(LogicIdUtil.bussinessId(), new BigDecimal(total), merSeqId, "", "");
                InfoPO.setStatus(DataStatusEnum.NORMAL.getType());
                InfoPO.setCreateTime(new Date());
                InfoPO.setTradeBeforeAmount(accountVO.getTradeBeforeAmount());
                InfoPO.setTradeAfterAmount(accountVO.getTradeAfterAmount());
                InfoPO.setThirdPartyPayment(2);
                InfoPO.setProjectId(projectId);
                InfoPO.setHandlingFee(accountVO.getHandlingFee());
                InfoPO.setTradeType(TradeTypeEnum.PROPERTY_WITHDRAW_CASH.getType());
                iOperateBalanceAccountDao.save(SqlUtil.durableData(InfoPO, PlatformConstants.TABLE_SAVE));
                //提现成功后查看该项目是否有默认使用的银行卡，如没有则将此次提现的银行卡做为默认使用银行卡
                if (iOperateWithdrawDao.getDefaultUserBankCard(accountVO.getProjectId()) == 0) {
                    iOperateWithdrawDao.updateDefaultUserBankCard(accountVO.getProjectId(), accountVO.getBankCardNo());
                }
                transferPropertyPO.setUpdateTime(new Date());
                iChinaPayTransferAccountDao.update(SqlUtil.durableData(transferPropertyPO,PlatformConstants.TABLE_UPDATE));
            }
        }

//        String[] cashIdArr = cashIds.split(",");
//        //由于银联转账每次请求响应时间不得小于60秒，故先将转账状态改为转账中，另开一个线程异步去处理转账业务逻辑
//        if(cashIdArr.length>0){
//            iChinaPayTransferAccountDao.updateTradeStatus(cashIdArr,myUserName);
//        }
//        cachedThreadPool.execute(() ->{
//            try{
//                for(String cashId : cashIdArr){
//                    //根据提现ID查询提现金额、手续费和所转账的银行卡等信息
//                    OperateTransferAccountVO accountVO = iChinaPayTransferAccountDao.getBankCardInfoByCashId(cashId);
//                    //获取银联的手续费
//                    String fee = iChinaPayTransferAccountDao.getChinaPayHandFee();
//                    if(StringUtils.isEmpty(fee)){
//                        fee = "2";
//                    }
//                    String merSeqId = LogicIdUtil.bussinessId().substring(0,16);
//                    if(accountVO!=null){
//                        String projectId = accountVO.getProjectId();
//                        String total = accountVO.getAmount().subtract(accountVO.getHandlingFee()).toString();
//                        ChinaPayTransactionBeanDTO beanDTO = new ChinaPayTransactionBeanDTO();
//                        beanDTO.setMerId(MERID);
//                        beanDTO.setMerDate(dateFormat.format(new Date()));
//                        beanDTO.setMerSeqId(merSeqId);
//                        beanDTO.setCardNo(accountVO.getBankCardNo());
//                        beanDTO.setUserName(accountVO.getUserName());
//                        beanDTO.setOpenBank(accountVO.getOpenBankName());
//                        beanDTO.setProv(accountVO.getProv());
//                        beanDTO.setCity(accountVO.getCity());
//                        beanDTO.setTransAmt(RandomUtil.changeToFen(Double.parseDouble(total)));
//                        beanDTO.setPurpose("转账");
//                        beanDTO.setFlag("01");
//                        beanDTO.setVersion(VERSION);
//                        beanDTO.setTermType("07");
//                        beanDTO.setPayMode("1");
//
//                        String Data = beanDTO.toString();
//                        String plainDataRequest = new String(Base64.encode(Data.getBytes()));
//
//                        //签名
//                        String chkValue = null;
//                        int KeyUsage = 0;
//                        PrivateKey key = new PrivateKey();
//                        boolean flage = key.buildKey(MERID, KeyUsage, MERKEY_PATH);
//                        if (flage == false) {
//                            System.out.println("buildkey error!");
//                            return;
//                        } else {
//                            SecureLink sl = new SecureLink(key);
//                            chkValue = sl.Sign(plainDataRequest);
//                        }
//                        beanDTO.setChkValue(chkValue);
//
//                        //连接Chinapay控台
//                        HttpClient httpClient = new HttpClient();
//                        System.out.println("HttpClient方法创建！");
//                        httpClient.getHttpConnectionManager().getParams()
//                                .setConnectionTimeout(60000);
//                        httpClient.getHttpConnectionManager().getParams().setSoTimeout(60000);
//                        //httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "GBK");
//                        httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
//                        PostMethod postMethod = new PostMethod(CHINAPAY_PAY_URL);
//                        System.out.println("Post方法创建！");
//
//                        //填入各个表单域的值
//                        NameValuePair[] data = {
//                                new NameValuePair("merId", MERID),
//                                new NameValuePair("merDate", dateFormat.format(new Date())),
//                                new NameValuePair("merSeqId", merSeqId),
//                                new NameValuePair("cardNo", accountVO.getBankCardNo()),
//                                new NameValuePair("usrName", accountVO.getUserName()),
//                                new NameValuePair("openBank", accountVO.getOpenBankName()),
//                                new NameValuePair("prov", accountVO.getProv()),
//                                new NameValuePair("city", accountVO.getCity()),
//                                new NameValuePair("transAmt", RandomUtil.changeToFen(Double.parseDouble(total))),
//                                new NameValuePair("purpose", "转账"),
//                                new NameValuePair("flag", "01"),
//                                new NameValuePair("version", VERSION),
//                                new NameValuePair("chkValue", chkValue),
//                                new NameValuePair("signFlag", "1"),
//                                new NameValuePair("termType", "07"),
//                                new NameValuePair("payMode", "1")
//                        };
//
//                        System.out.println(data);
//                        //System.out.println("Ora交易提交报文：merId=" + MERID + "&merDate=" + merDate + "&merSeqId=" + merSeqId + "&cardNo=" + cardNo + "&usrName=" + usrName + "&openBank=" + openBank + "&prov=" + prov + "&city=" + city + "&transAmt=" + transAmt + "&purpose=" + purpose + "&flag=" + flag + "&version=" + version + "&chkValue=" + chkValue + "&signFlag=" + signFlag + "&termType=" + termType);
//                        // 将表单的值放入postMethod中
//                        postMethod.setRequestBody(data);
//                        // 执行postMethod
//                        try {
//                            httpClient.executeMethod(postMethod);
//                        }catch (Exception e) {
//                            e.printStackTrace();
//                        }
//                        // 读取内容
//                        InputStream resInputStream = null;
//                        try {
//                            resInputStream = postMethod.getResponseBodyAsStream();
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        }
//                        // 处理内容
//                        BufferedReader reader = new BufferedReader(new InputStreamReader(resInputStream));
//                        String tempBf = null;
//                        StringBuffer html = new StringBuffer();
//                        while ((tempBf = reader.readLine()) != null) {
//                            html.append(tempBf);
//                        }
//                        String resMes = html.toString();
//                        System.out.println("交易返回报文：" + resMes);
//                        int dex = resMes.lastIndexOf("&");
//
//                        //拆分页面应答数据
//                        String str[] = resMes.split("&");
//                        //提取返回数据
//                        if (str.length == 10) {
//                            int Res_Code = str[0].indexOf("=");
//                            int Res_merId = str[1].indexOf("=");
//                            int Res_merDate = str[2].indexOf("=");
//                            int Res_merSeqId = str[3].indexOf("=");
//                            int Res_cpDate = str[4].indexOf("=");
//                            int Res_cpSeqId = str[5].indexOf("=");
//                            int Res_transAmt = str[6].indexOf("=");
//                            int Res_stat = str[7].indexOf("=");
//                            int Res_cardNo = str[8].indexOf("=");
//                            int Res_chkValue = str[9].indexOf("=");
//
//                            String responseCode = str[0].substring(Res_Code + 1);
//                            String MerId = str[1].substring(Res_merId + 1);
//                            String MerDate = str[2].substring(Res_merDate + 1);
//                            String MerSeqId = str[3].substring(Res_merSeqId + 1);
//                            String CpDate = str[4].substring(Res_cpDate + 1);
//                            String CpSeqId = str[5].substring(Res_cpSeqId + 1);
//                            String TransAmt = str[6].substring(Res_transAmt + 1);
//                            String Stat = str[7].substring(Res_stat + 1);
//                            String CardNo = str[8].substring(Res_cardNo + 1);
//                            String ChkValue = str[9].substring(Res_chkValue + 1);
//
//                            System.out.println("responseCode=" + responseCode);
//                            System.out.println("merId=" + MerId);
//                            System.out.println("merDate=" + MerDate);
//                            System.out.println("merSeqId=" + MerSeqId);
//                            System.out.println("transAmt=" + TransAmt);
//                            System.out.println("cpDate=" + CpDate);
//                            System.out.println("cpSeqId=" + CpSeqId);
//                            System.out.println("Stat=" + Stat);
//                            System.out.println("cardNo=" + CardNo);
//                            System.out.println("chkValue=" + ChkValue);
//                            String msg = resMes.substring(0,dex);
//                            String plainData = new String(Base64.encode(msg.getBytes()));
//                            System.out.println("需要验签的字段：" + msg);
//
//                            //对收到的ChinaPay应答传回的域段进行验签
//                            boolean buildOK = false;
//                            boolean res = false;
//                            try {
//                                buildOK = key.buildKey("999999999999999", KeyUsage, PUBKEY_PATH);
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//                            if (!buildOK) {
//                                System.out.println("build error!");
//                                return;
//                            }
//
//                            SecureLink sl = new SecureLink(key);
//                            res=sl.verifyAuthToken(plainData,ChkValue);
//                            System.out.println(res);
//                            if (res){
//                                System.out.println("验签数据正确!");
//                                OperateTransferPropertyPO transferPropertyPO = new OperateTransferPropertyPO(accountVO.getCashId());
//                                if(Stat.equals("s")){
//                                    transferPropertyPO.setTradeStatus(ChinaPayTradeStatusEnum.TRADE_SUCCESS.getType());
//                                    transferPropertyPO.setTradeTime(new Date());
//                                    transferPropertyPO.setSerualNumber(merSeqId);
//                                    //保存资金变动明细 银联转账备付金变化明细
//                                    AmountChangeInfoPO changeInfoPO = new AmountChangeInfoPO(LogicIdUtil.bussinessId(),new BigDecimal(total),merSeqId, "","");
//                                    changeInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
//                                    changeInfoPO.setCreateTime(new Date());
//                                    String accountBalance = this.getAccountBalance();
//                                    changeInfoPO.setTradeBeforeAmount(BigDecimal.valueOf(Double.valueOf(accountBalance)/100).add(new BigDecimal(total)).add(new BigDecimal(fee)));
//                                    changeInfoPO.setTradeAfterAmount(BigDecimal.valueOf(Double.valueOf(accountBalance)/100));
//                                    changeInfoPO.setThirdPartyPayment(2);
//                                    changeInfoPO.setTradeType(TradeTypeEnum.CHINA_PAY_FEE.getType());
//                                    changeInfoPO.setHandlingFee(new BigDecimal(fee));
//                                    iOperateBalanceAccountDao.save(SqlUtil.durableData(changeInfoPO, PlatformConstants.TABLE_SAVE));
//
//                                    //保存资金变动明细 物业提现变化明细
//                                    /*String allowedCashWithdrawl = iOperateBalanceAccountDao.getaAllowedCashWithdrawl(projectId);
//                                    if(StringUtils.isEmpty(allowedCashWithdrawl)){
//                                        allowedCashWithdrawl = "0";
//                                    }*/
//                                    AmountChangeInfoPO InfoPO = new AmountChangeInfoPO(LogicIdUtil.bussinessId(),new BigDecimal(total),merSeqId, "","");
//                                    InfoPO.setStatus(DataStatusEnum.NORMAL.getType());
//                                    InfoPO.setCreateTime(new Date());
//                                    InfoPO.setTradeBeforeAmount(accountVO.getTradeBeforeAmount());
//                                    InfoPO.setTradeAfterAmount(accountVO.getTradeAfterAmount());
//                                    InfoPO.setThirdPartyPayment(2);
//                                    InfoPO.setProjectId(projectId);
//                                    InfoPO.setHandlingFee(accountVO.getHandlingFee());
//                                    InfoPO.setTradeType(TradeTypeEnum.PROPERTY_WITHDRAW_CASH.getType());
//                                    iOperateBalanceAccountDao.save(SqlUtil.durableData(InfoPO, PlatformConstants.TABLE_SAVE));
//
//                                    //提现成功后查看该项目是否有默认使用的银行卡，如没有则将此次提现的银行卡做为默认使用银行卡
//                                    if(iOperateWithdrawDao.getDefaultUserBankCard(accountVO.getProjectId())==0){
//                                        iOperateWithdrawDao.updateDefaultUserBankCard(accountVO.getProjectId(),accountVO.getBankCardNo());
//                                    }
//                                } else if(Stat.equals("6") || Stat.equals("9")){
//                                    transferPropertyPO.setTradeStatus(ChinaPayTradeStatusEnum.TRADE_FAIL.getType());
//                                    transferPropertyPO.setSerualNumber(merSeqId);
//                                    transferPropertyPO.setUpdateTime(new Date());
//                                    transferPropertyPO.setRemark("银行退单，交易失败");
//
//                                    //银联交易失败后将所交易金额更新至项目中物业可提现余额和实时余额需更新 发送消息队列
//                                    /*JSONObject json = new JSONObject();
//                                    json.put("arithmeticFlag", "0");//运算: 0加,1减
//                                    json.put("amount", Double.valueOf(String.valueOf(accountVO.getAmount())));//金额
//                                    json.put("projectId", projectId);//项目编号*/
//                                    Map<String,Object> params=new HashMap<>();
//                                    params.put("arithmeticFlag", "0");//运算: 0加,1减
//                                    params.put("amount", Double.valueOf(String.valueOf(accountVO.getAmount())));//金额
//                                    params.put("projectId", projectId);//项目编号
//                                    params.put("updateNameFlag","");//0可提现余额,1实时余额   为空都更新
//
//                                    messageSender.send(RabbitMQConstant.RABBITMQ_PROJECT_AMOUNT_MANAGER_QUEUE, JSON.toJSONString(params),
//                                            RabbitMQConstant.RABBITMQ_PAY_EXCHANGE,
//                                            RabbitMQConstant.RABBITMQ_PROJECT_AMOUNT_ROUTING_KEY);
//                                }else{
//                                    transferPropertyPO.setSerualNumber(merSeqId);
//                                    transferPropertyPO.setUpdateTime(new Date());
//                                    iChinaPayTransferAccountDao.update(SqlUtil.durableData(transferPropertyPO,PlatformConstants.TABLE_UPDATE));
//                                    continue;
//                                }
//                                transferPropertyPO.setUpdateTime(new Date());
//                                iChinaPayTransferAccountDao.update(SqlUtil.durableData(transferPropertyPO,PlatformConstants.TABLE_UPDATE));
//                            }
//                            else {
//                                System.out.println("签名数据不匹配！");
//                            }
//                        }
//
//                        //交易失败应答
//                        if(str.length == 2){
//                            int Res_Code = str[0].indexOf("=");
//                            int Res_chkValue = str[1].indexOf("=");
//
//                            String responseCode = str[0].substring(Res_Code+1);
//                            String ChkValue = str[1].substring(Res_chkValue+1);
//                            System.out.println("responseCode=" + responseCode);
//                            System.out.println("chkValue=" + ChkValue);
//
//                            String plainData = str[0];
//                            String plainData1 = new String(Base64.encode(plainData.getBytes()));
//                            System.out.println("需要验签的字段：" + plainData);
//
//
//                            //对收到的ChinaPay应答传回的域段进行验签
//                            boolean buildOK = false;
//                            boolean res = false;
//                            try {
//                                buildOK = key.buildKey("999999999999999", KeyUsage, PUBKEY_PATH);
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//                            if (!buildOK) {
//                                System.out.println("build error!");
//                                return;
//                            }
//
//                            SecureLink sl = new SecureLink(key);
//                            res=sl.verifyAuthToken(plainData1,ChkValue);
//                            System.out.println(res);
//                            if (res){
//                                System.out.println("验签数据正确!");
//
//                                //商户备付金余额不足返回前端界面
//                                OperateTransferPropertyPO transferPropertyPO = new OperateTransferPropertyPO(accountVO.getCashId());
//                                transferPropertyPO.setSerualNumber(merSeqId);
//                                transferPropertyPO.setTradeStatus(ChinaPayTradeStatusEnum.TRADE_FAIL.getType());
//                                if(responseCode.equals("0100")) {
//                                    transferPropertyPO.setRemark("商户提交的字段长度、格式错误");
//                                }
//                                if(responseCode.equals("0101")) {
//                                    transferPropertyPO.setRemark("商户验签错误");
//                                }
//                                if(responseCode.equals("0102")) {
//                                    transferPropertyPO.setRemark("手续费计算出错");
//                                }
//                                if(responseCode.equals("0103")) {
//                                    transferPropertyPO.setRemark("商户备付金帐户余额不足");
//                                }
//                                if(responseCode.equals("0104")) {
//                                    transferPropertyPO.setRemark("操作拒绝");
//                                }
//                                if(responseCode.equals("0105")) {
//                                    transferPropertyPO.setRemark("重复交易");
//                                }
//                                transferPropertyPO.setUpdateTime(new Date());
//                                iChinaPayTransferAccountDao.update(SqlUtil.durableData(transferPropertyPO,PlatformConstants.TABLE_UPDATE));
//
//                                //银联交易失败后将所交易金额更新至项目中物业可提现余额和实时余额需更新 发送消息队列
//                                Map<String,Object> params=new HashMap<>();
//                                params.put("arithmeticFlag", "0");//运算: 0加,1减
//                                params.put("amount", Double.valueOf(String.valueOf(accountVO.getAmount())));//金额
//                                params.put("projectId", projectId);//项目编号
//                                params.put("updateNameFlag","");//0可提现余额,1实时余额   为空都更新
//
//                                messageSender.send(RabbitMQConstant.RABBITMQ_PROJECT_AMOUNT_MANAGER_QUEUE, JSON.toJSONString(params),
//                                        RabbitMQConstant.RABBITMQ_PAY_EXCHANGE,
//                                        RabbitMQConstant.RABBITMQ_PROJECT_AMOUNT_ROUTING_KEY);
//                            }
//                            else {
//                                System.out.println("签名数据不匹配！");
//                            }
//                            return;
//                        }
//                    }
//                }
//            }catch (Exception e){
//                e.printStackTrace();
//            }
//        });
    }
    /**
     * <desc>
     *      查询备付金余额
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018-09-20
     */
    @Override
    public String getAccountBalance() throws Exception{
        String DataRequest = MERID + VERSION;
        String plainDataReturn = new String(Base64.encode(DataRequest.getBytes()));
        //签名
        String chkValue = null;
        int KeyUsage = 0;
        PrivateKey key = new PrivateKey();
        key.buildKey(MERID, KeyUsage, MERKEY_PATH);
        SecureLink sl = new SecureLink(key);
        chkValue = sl.Sign(plainDataReturn);

        HttpClient httpClient = new HttpClient();
        httpClient.getHttpConnectionManager().getParams()
                .setConnectionTimeout(60000);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(60000);
        httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
        PostMethod postMethod = new PostMethod(BALANCE_QUERY);
        //填入各个表单域的值
        NameValuePair[] data = {
                new NameValuePair("merId", MERID),
                new NameValuePair("version", VERSION),
                new NameValuePair("chkValue",chkValue),
                new NameValuePair("signFlag", SIGN_FLAG)
        };

        // 将表单的值放入postMethod中
        postMethod.setRequestBody(data);
        // 执行postMethod
        try {
            httpClient.executeMethod(postMethod);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 读取内容
        InputStream resInputStream = null;
        try {
            resInputStream = postMethod.getResponseBodyAsStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 处理内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(resInputStream));
        String tempBf = null;
        StringBuffer html=new StringBuffer();
        while((tempBf = reader.readLine()) != null){
            html.append(tempBf);
        }
        String resMes = html.toString();
        LOG.info("单笔查询返回报文：" + resMes);
        int dex = resMes.lastIndexOf("|");
        String Res_Code = resMes.substring(0,3);

        //提取返回数据
        if(Res_Code.equals("000")){
            String Res_stat = resMes.substring(dex-2,dex-1);
            String Res_chkValue = resMes.substring(dex+1);
            System.out.println("Res_Code=" + Res_Code);
            System.out.println("Res_stat=" + Res_stat);
            System.out.println("Res_chkValue=" + Res_chkValue);

            String plainData = resMes.substring(0,dex+1);
            String accountBalance = plainData.substring(plainData.substring(0,dex).lastIndexOf("|")+1,dex);
            LOG.info("查询账户余额：" + accountBalance);
            LOG.info("需要验签的字段：" + plainData);
            String Data = new String(Base64.encode(plainData.getBytes()));
            System.out.println("转换成Base64后数据：" + Data);
            //对收到的ChinaPay应答传回的域段进行验签
            boolean buildOK = false;
            boolean res = false;
            try {
                buildOK = key.buildKey("999999999999999", KeyUsage, PUBKEY_PATH);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!buildOK) {
                System.out.println("build error!");
                return null;
            }
            res=sl.verifyAuthToken(Data,Res_chkValue);
            System.out.println(res);
            if (res){
                System.out.println("验签数据正确!");
            } else {
                System.out.println("签名数据不匹配！");
            }
            return accountBalance;
        } else {
            String Res_chkValue = resMes.substring(dex+1);
            String plainData = resMes.substring(0,dex+1);
            System.out.println("需要验签的字段：" + plainData);
            String Data = new String(Base64.encode(plainData.getBytes()));
            System.out.println("转换成Base64后数据：" + Data);

            //对收到的ChinaPay应答传回的域段进行验签
            boolean buildOK = false;
            boolean res = false;
            try {
                buildOK = key.buildKey("999999999999999", KeyUsage, PUBKEY_PATH);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!buildOK) {
                System.out.println("build error!");
                return null;
            }
            res=sl.verifyAuthToken(Data,Res_chkValue);
            System.out.println(res);
            if (res){
                System.out.println("验签数据正确!");
            }
            else {
                System.out.println("签名数据不匹配！");
            }
            return null;
        }
    }

    /**
     * <desc>
     *      查询将要转账的总金额
     * <desc/>
     *
     * @param cashIds 提现记录ID,逗号分隔
     * @return
     * @author Juguang.S
     * @createDate 2018-09-23
     */
    @Override
    public String getTotal(String cashIds) {
        return iChinaPayTransferAccountDao.getTotal(cashIds.split(","));
    }

    /**
     * <desc>
     *      根据流水号调用银联单笔查询接口
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018-09-23
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String queryOrder(String merDate,String merSeqId) throws Exception{
        /*SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
        SimpleDateFormat sf2 = new SimpleDateFormat("yyyyMMdd");*/
        String DataRequest = MERID + merDate + merSeqId + VERSION;
        String plainDataReturn = new String(Base64.encode(DataRequest.getBytes()));
        //签名
        String chkValue = null;
        int KeyUsage = 0;
        PrivateKey key = new PrivateKey();
        key.buildKey(MERID, KeyUsage, MERKEY_PATH);
        SecureLink sl = new SecureLink(key);
        chkValue = sl.Sign(plainDataReturn);
        System.out.println("签名内容:"+ chkValue);

        HttpClient httpClient = new HttpClient();
        httpClient.getHttpConnectionManager().getParams()
                .setConnectionTimeout(60000);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(60000);
        System.out.println("HttpClient方法创建！");
        httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
        PostMethod postMethod = new PostMethod(QUERY_ORDER);
        System.out.println("Post方法创建！");
        //填入各个表单域的值
        NameValuePair[] data = {
                new NameValuePair("merId", MERID),
                new NameValuePair("merDate", merDate),
                new NameValuePair("merSeqId", merSeqId),
                new NameValuePair("version", VERSION),
                new NameValuePair("chkValue",chkValue),
                new NameValuePair("signFlag", SIGN_FLAG)
        };
        // 将表单的值放入postMethod中
        postMethod.setRequestBody(data);
        // 执行postMethod
        try {
            httpClient.executeMethod(postMethod);
        }catch (Exception e) {
            e.printStackTrace();
        }
        // 读取内容
        InputStream resInputStream = null;
        try {
            resInputStream = postMethod.getResponseBodyAsStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 处理内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(resInputStream));
        String tempBf = null;
        StringBuffer html=new StringBuffer();
        while((tempBf = reader.readLine()) != null){
            html.append(tempBf);
        }
        String resMes = html.toString();
        System.out.println("单笔查询返回报文：" + resMes);
        int dex = resMes.lastIndexOf("|");
        String Res_Code = resMes.substring(0,3);
        //提取返回数据
        if(Res_Code.equals("000")){
            String check = resMes.substring(dex-8,dex);
            Pattern pattern = Pattern.compile("[0-9]*");
            Matcher isNum = pattern.matcher(check);
            String Res_stat ="";
            if( !isNum.matches() ){
                Res_stat = resMes.substring(dex-2,dex-1);
            }else{
                Res_stat = resMes.substring(dex-10,dex-9);
            }

            String Res_chkValue = resMes.substring(dex+1);
            System.out.println("Res_Code=" + Res_Code);
            System.out.println("Res_stat=" + Res_stat);
            System.out.println("Res_chkValue=" + Res_chkValue);
            String plainData = resMes.substring(0,dex+1);
            String Data = new String(Base64.encode(plainData.getBytes()));

            //对收到的ChinaPay应答传回的域段进行验签
            boolean buildOK = false;
            boolean res = false;
            try {
                buildOK = key.buildKey("999999999999999", KeyUsage, PUBKEY_PATH);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!buildOK) {
                System.out.println("build error!");
            }
            res=sl.verifyAuthToken(Data,Res_chkValue);
            System.out.println(res);
            if (res){
                System.out.println("验签数据正确!");
            } else {
                System.out.println("签名数据不匹配！");
            }
            return Res_stat;
        } else {
            String Res_chkValue = resMes.substring(dex+1);
            System.out.println("Res_Code=" + Res_Code);
            System.out.println("Res_chkValue=" + Res_chkValue);
            String plainData = resMes.substring(0,dex+1);
            String Data = new String(Base64.encode(plainData.getBytes()));
            //对收到的ChinaPay应答传回的域段进行验签
            boolean buildOK = false;
            boolean res = false;
            try {
                buildOK = key.buildKey("999999999999999", KeyUsage, PUBKEY_PATH);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!buildOK) {
                System.out.println("build error!");
            }
            res=sl.verifyAuthToken(Data,Res_chkValue);
            System.out.println(res);
            if (res){
                System.out.println("验签数据正确!");
            }
            else {
                System.out.println("签名数据不匹配！");
            }
        }
        return null;
    }

    /**
     * <desc>
     *      获取银联的手续费
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018-10-10
     */
    @Override
    public String getChinaPayHandFee(){
        return iChinaPayTransferAccountDao.getChinaPayHandFee();
    }

    /**
     * <desc>
     *      查询银联交易结果状态
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018-09-25
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void getTradeStatus() throws Exception {
        //获取未超时且状态为处理中的数据
        List<ChinaPayWithdrawVO> lists = iOperateWithdrawDao.getTradeInfoByStatus();
        //获取银联的手续费
        String fee = iChinaPayTransferAccountDao.getChinaPayHandFee();
        if(StringUtils.isEmpty(fee)){
            fee = "2";
        }
        if(lists.size()>0){
            for(ChinaPayWithdrawVO withdrawVO : lists){
                long tradeTime = withdrawVO.getSendTradeTime().getTime();
                long nowTime = new Date().getTime();
                //如果距离向银联发起交易时间已超过三天，则被视为超时处理
                if((int)(nowTime-tradeTime)/(1000*60)>=PlatformConstants.CHINA_PAY_OUTTIME_TIME){
                    OperateTransferPropertyPO propertyPO = new OperateTransferPropertyPO(withdrawVO.getCashId());
                    propertyPO.setUpdateTime(new Date());
                    propertyPO.setIsTimeout(OutTimeEnum.OUT_TIME.getType());
                    iOperateWithdrawDao.update(SqlUtil.durableData(propertyPO,PlatformConstants.TABLE_UPDATE));
                }else{
                    String resultStr = this.queryOrder(dateFormat.format(withdrawVO.getSendTradeTime()),withdrawVO.getSerualNumber());
                    LOG.info("【查询银联订单交易状态】："+resultStr);
                    //交易成功
                    if("s".equals(resultStr)){
                        OperateTransferPropertyPO propertyPO = new OperateTransferPropertyPO(withdrawVO.getCashId());
                        propertyPO.setTradeStatus(ChinaPayTradeStatusEnum.TRADE_SUCCESS.getType());
                        propertyPO.setTradeTime(new Date());
                        propertyPO.setUpdateTime(new Date());
                        propertyPO.setSerualNumber(withdrawVO.getSerualNumber());
                        propertyPO.setIsTimeout(OutTimeEnum.NOT_OUT_TIME.getType());
                        iOperateWithdrawDao.update(SqlUtil.durableData(propertyPO,PlatformConstants.TABLE_UPDATE));

                        //保存资金变动明细
                        String total = withdrawVO.getAmount().subtract(withdrawVO.getHandlingFee()).toString();
                        AmountChangeInfoPO changeInfoPO = new AmountChangeInfoPO(LogicIdUtil.bussinessId(),new BigDecimal(total),withdrawVO.getSerualNumber(), "","");
                        changeInfoPO.setStatus(DataStatusEnum.NORMAL.getType());
                        changeInfoPO.setCreateTime(new Date());
                        String accountBalance = this.getAccountBalance();
                        changeInfoPO.setTradeBeforeAmount(BigDecimal.valueOf(Double.valueOf(accountBalance)/100).add(new BigDecimal(total)).add(new BigDecimal(fee)));
                        changeInfoPO.setTradeAfterAmount(BigDecimal.valueOf(Double.valueOf(accountBalance)/100));
                        changeInfoPO.setTradeAmount(new BigDecimal(total));
                        changeInfoPO.setThirdPartyPayment(2);
                        changeInfoPO.setTradeType(TradeTypeEnum.CHINA_PAY_FEE.getType());
                        changeInfoPO.setHandlingFee(new BigDecimal(fee));
                        iOperateBalanceAccountDao.save(SqlUtil.durableData(changeInfoPO, PlatformConstants.TABLE_SAVE));

                        //保存资金变动明细 物业提现变化明细
                        String allowedCashWithdrawl = iOperateBalanceAccountDao.getaAllowedCashWithdrawl(withdrawVO.getProjectId());
                        if(StringUtils.isEmpty(allowedCashWithdrawl)){
                            allowedCashWithdrawl = "0";
                        }
                        AmountChangeInfoPO InfoPO = new AmountChangeInfoPO(LogicIdUtil.bussinessId(),new BigDecimal(total),withdrawVO.getSerualNumber(), "","");
                        InfoPO.setStatus(DataStatusEnum.NORMAL.getType());
                        InfoPO.setCreateTime(new Date());
                        InfoPO.setTradeBeforeAmount(withdrawVO.getTradeBeforeAmount());
                        InfoPO.setTradeAfterAmount(withdrawVO.getTradeAfterAmount());
                        InfoPO.setThirdPartyPayment(2);
                        InfoPO.setProjectId(withdrawVO.getProjectId());
                        InfoPO.setHandlingFee(withdrawVO.getHandlingFee());
                        InfoPO.setTradeType(TradeTypeEnum.PROPERTY_WITHDRAW_CASH.getType());
                        iOperateBalanceAccountDao.save(SqlUtil.durableData(InfoPO, PlatformConstants.TABLE_SAVE));

                        //提现成功后查看该项目是否有默认使用的银行卡，如没有则将此次提现的银行卡做为默认使用银行卡
                        if(iOperateWithdrawDao.getDefaultUserBankCard(withdrawVO.getProjectId())==0){
                            iOperateWithdrawDao.updateDefaultUserBankCard(withdrawVO.getProjectId(),withdrawVO.getBankCardNo());
                        }
                    }
                    else if(resultStr.equals("6") || resultStr.equals("9")){
                        LOG.info("【查询银联订单交易状态】："+resultStr);
                        OperateTransferPropertyPO propertyPO = new OperateTransferPropertyPO(withdrawVO.getCashId());
                        propertyPO.setTradeStatus(ChinaPayTradeStatusEnum.TRADE_FAIL.getType());
                        propertyPO.setUpdateTime(new Date());
                        propertyPO.setSerualNumber(withdrawVO.getSerualNumber());
                        propertyPO.setIsTimeout(OutTimeEnum.NOT_OUT_TIME.getType());
                        iOperateWithdrawDao.update(SqlUtil.durableData(propertyPO,PlatformConstants.TABLE_UPDATE));

                        Map<String,Object> params=new HashMap<>();
                        params.put("arithmeticFlag", "0");//运算: 0加,1减
                        params.put("amount", Double.valueOf(String.valueOf(withdrawVO.getAmount())));//金额
                        params.put("projectId", withdrawVO.getProjectId());//项目编号
                        params.put("updateNameFlag","");//0可提现余额,1实时余额   为空都更新

                        messageSender.send(RabbitMQConstant.RABBITMQ_PROJECT_AMOUNT_MANAGER_QUEUE, JSON.toJSONString(params),
                                RabbitMQConstant.RABBITMQ_PAY_EXCHANGE,
                                RabbitMQConstant.RABBITMQ_PROJECT_AMOUNT_ROUTING_KEY);
                    }
                    else{
                        continue;
                    }
                }
            }
        }
    }
}
